/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author xxxcsg
 */


#include "dev_util.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <memory.h>

#include <fcntl.h>
#include <sys/mman.h>

#include "cJSON.h"
#include "memmap.h"
#include "parameter.h"

#ifdef DEVICE_HI3519DV500
#define REG_CPU_TEMPERTURE (0x1102a008UL)
#define REG_CPU_FREQ (0x11012044UL)
#elif DEVICE_HISS928V100
#define REG_CPU_TEMPERTURE (0x1102e008UL)
#define REG_CPU_FREQ (0x11012040UL)
#else
#define REG_CPU_TEMPERTURE (0x0UL)
#define REG_CPU_FREQ (0x0UL)
#endif

#define CHIPID_UNIQUE_ID_OFFSET (0x011021200UL)

#define MAP_SIZE sizeof(unsigned int) * 5


static int get_chip_temp(unsigned long reg,unsigned int *outFreq)
{
    if(reg == 0)
    {
        return EXIT_FAILURE;
    }

    const unsigned int *p_mem  = NULL;
    void *addr = NULL;
    unsigned long out_size_in_page = 0;

    p_mem = (unsigned int *)memmap(reg, sizeof(unsigned int),&addr,&out_size_in_page);
    if (p_mem == NULL)
    {
        printf("memmap failed\n");
        return EXIT_FAILURE;
    }

    // memset(outStr, '\0', outLen);
    // snprintf(outStr, outLen, "%08x",*p_mem);
    *outFreq = (*p_mem) & 0xfff;

    if(addr == NULL)
    {
        printf("memunmap failed\n");
        return EXIT_SUCCESS;
    }
    memunmap(addr,out_size_in_page);
    return EXIT_SUCCESS;
}

static int get_chip_freq(const unsigned long reg,unsigned int *outFreq)
{
    if(reg == 0)
    {
        return EXIT_FAILURE;
    }
    
    const unsigned int *p_mem  = NULL;
    void *addr = NULL;
    unsigned long out_size_in_page = 0;
    
    p_mem = (unsigned int *)memmap(reg, sizeof(unsigned int),&addr,&out_size_in_page);
    if (p_mem == NULL)
    {
        printf("memmap failed\n");
        return EXIT_FAILURE;
    }
    
    // memset(outFreq, '\0', outLen);
    // snprintf(outFreq, outLen, "%08x",*p_mem);
    *outFreq = (*p_mem) & 0xfff;

    if(addr == NULL)
    {
        printf("memunmap failed\n");
        return EXIT_SUCCESS;
    }
    memunmap(addr,out_size_in_page);

    return EXIT_SUCCESS;
}

double get_cpu_temperture(void)
{
    unsigned int sensor_result = 0;
    int ret = 0;
    double temperature = 0.0;

    ret = get_chip_temp(REG_CPU_TEMPERTURE,&sensor_result);
    if(ret != 0)
    {
        return temperature;
    }
    // printf("sensor_result:%d\n", sensor_result);
#ifdef DEVICE_HI3519DV500
    temperature = ((double)(sensor_result - 132) / (double)808) * (double)165 - (double)40;
#elif DEVICE_HISS928V100
    temperature = ((double)(sensor_result - 146) / (double)718) * (double)165 - (double)40;
#endif
    // printf("%.2lf\n", temperature);

    return temperature;
}

int get_cpu_freq(void)
{
    int freq = 0;
    int ret = 0;
    unsigned int sensor_result = 0;

    ret = get_chip_freq(REG_CPU_FREQ,&sensor_result);
    if(ret != 0)
    {
        return 0;
    }
    // printf("sensor_result:%d\n", sensor_result);

#ifdef DEVICE_HI3519DV500
    freq = sensor_result & 0x7;

    switch(freq)
    {
        case 0:
            freq = 24;
            break;
        case 1:
            freq = 675;
            break;
        // case 2:
        //     freq = 24;
        //     break;
        case 3:
            freq = 792;
            break;
        case 4:
            freq = 833;
            break;
        case 5:
            freq = 900;
            break;
        case 6:
            freq = 1000;
            break;
        default:
            freq = 0;
            break; 
    }
#elif DEVICE_HISS928V100
    int fcmClk = (sensor_result >> 10) &0x3;
    int coreClk = (sensor_result >> 8) & 0x3;

    if(coreClk == fcmClk == 0x0)
    {
        freq = 24;
    }
    else if(coreClk == 0x1 && fcmClk == 0x0)
    {
        freq = 24;
    }
    else if(coreClk == 0x2 && fcmClk == 0x0)
    {
        freq = 1188;
    }
    else if(coreClk == 0x0 && fcmClk == 0x1)
    {
        freq = 896;
    }
    else if(coreClk == 0x1 && fcmClk == 0x1)
    {
        freq = 896;
    }
    else if(coreClk == 0x2 && fcmClk == 0x1)
    {
        freq = 1188;
    }
#endif
    // printf("freq:%d\n", freq);

    return freq;
}



int get_chip_id(char* outStr, size_t outLen)
{
    const unsigned int *p_mem  = NULL;
    void *addr = NULL;
    unsigned long out_size_in_page = 0;
    p_mem = (unsigned int *)memmap(CHIPID_UNIQUE_ID_OFFSET, MAP_SIZE,&addr,&out_size_in_page);
    if (p_mem == NULL)
    {
        printf("memmap failed\n");
        return EXIT_FAILURE;
    }
    
    memset(outStr, '\0', outLen);
    snprintf(outStr, outLen, "%08x%08x%08x%08x%08x",*(p_mem + 4), *(p_mem + 3), *(p_mem + 2), *(p_mem + 1), *(p_mem + 0));
    
    if(addr == NULL)
    {
        printf("memunmap failed\n");
        return EXIT_SUCCESS;
    }
    memunmap(addr,out_size_in_page);

    return EXIT_SUCCESS;
}

// int get_os_full_name(char* outStr, size_t outLen)
// {
//     const char *osName = NULL;
    
//     osName = GetOSFullName();
//     if (osName == NULL) {
//         osName = "";
//     }
    
//     memset(outStr, '\0', outLen);
//     snprintf(outStr, outLen, osName);
    
//     return EXIT_SUCCESS;
// }

// int get_os_display_version(char* outStr, size_t outLen)
// {
//     const char *displayVersion = NULL;
    
//     displayVersion = GetDisplayVersion();
//     if (displayVersion == NULL) {
//         displayVersion = "";
//     }

//     memset(outStr, '\0', outLen);
//     snprintf(outStr, outLen, displayVersion);
    
//     return EXIT_SUCCESS;
// }

// void to_hex(char *src, int len, char *dst)
// {
//     static char hex_table[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

//     if (len < 0)
//     {
//         return;
//     }

//     while (len--)
//     {
//         *(dst++) = hex_table[*src >> 4];
//         *(dst++) = hex_table[*(src++) & 0x0f];
//     }
// }